package com.lagou.config;

import com.lagou.util.ClassUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

/**
 * @author: wudong
 * @create: 2021-05-27 17:35
 **/
public class BeanDefinitionRegistry extends SimpleAliasRegistry implements Registry<BeanDefinition>{

    private Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>();


    @Override
    public void registerBeanDefinition(String name, BeanDefinition beanDefinition) {
        // TODO 通过方法构造bean的(例如在配置类里面申明方法创建bean)会出现同一个接口的不同实现类无法注册
        // 暂时没有好的解决办法

        Class<?> beanClass = beanDefinition.getBeanClass();

        String beanName = beanClass.getName();
        if(this.beanDefinitionMap.containsKey(beanName)){
            throw new IllegalStateException(beanName + "重复注册");
        }

        this.beanDefinitionMap.put(beanName,beanDefinition);

        List<String> alias = beanDefinition.getBeanNames();
        if(alias != null){
            for (String alia : alias) {
                if(alia.isEmpty()){
                    continue;
                }
                registerAlias(beanName,alia);
            }
        }

        Consumer<Class<?>> classConsumer = aclass -> {
            registerAlias(beanName,aclass.getName());
        };
        ClassUtil.findAllClass(beanClass,classConsumer);
    }

    @Override
    public BeanDefinition getBeanDefinition(String name) {
        BeanDefinition obj = beanDefinitionMap.get(name);
        if(obj == null){
            String realName = this.getRealName(name);
            if(realName != null){
                obj = beanDefinitionMap.get(realName);
            }
        }
        return obj;
    }

    @Override
    public List<RegisterInfo<BeanDefinition>> listAllRegister() {
        Set<Map.Entry<String, BeanDefinition>> entries = this.beanDefinitionMap.entrySet();
        List<RegisterInfo<BeanDefinition>> beans = new ArrayList<>();

        for (Map.Entry<String, BeanDefinition> entry : entries) {
            RegisterInfo<BeanDefinition> info = new RegisterInfo<BeanDefinition>(entry.getValue(),entry.getKey());
            beans.add(info);
        }
        return beans;
    }
}
